<?php
/**
 * @author jonathan <jo.link.noir@gmail.com>
 * @version 1.0: jo_link_noir
 * @date 14-04-2010
 */
class U1_Move_Spy extends U1_Move_Attack
{
	/** @var string*/
	protected $orderName = 'spy';


	/**
	 * Méthode appelé pour effectué une action sur une planète habité
	 * @param SW_Units $units
	 * @param U1_Planet $planetEnd
	 * @return bool : true si la flotte doit être détruite. false si la flotte doit revenir.
	 */
	protected function process(SW_Units $units, U1_Planet $planetEnd)
	{
		if ($units->offsetExists(4))
		{
			$probe = $units->offsetGet(4);
			$count = $probe->getCount();

			//récupère l'objet des recherches et termine les constructions
			$researchEnd = $this->getStructureAndFinishCompletLists($planetEnd, U1_Research::INDEX, $this->endPoint);
			//récupère l'objet des batiments et termine les constructions
			$buildingEnd = $this->getStructureAndFinishCompletLists($planetEnd, U1_Building::INDEX, $this->endPoint);

			$detect = sqrt(1
				+ $researchEnd->getLevelSumGroup(17) //technique d'espionnage
				+ (1 + $researchEnd->getLevelSumGroup(18) * 5) //détection de vaisseaux
				* (
					$buildingEnd->getLevelSumGroup(8) //radar
					+ $buildingEnd->getLevelSumGroup(9) * 3 //radar avancée
				)
			);
			$planetStart = U1_Planet::factoryContainsPlanetId($this->startPoint);
			//l'efficacité des sondes (proportionnel au nombre) est diminué par leurs nombres (moins)
			$spy = floor(sqrt($count * (1 +
					$this->getStructureAndFinishCompletLists($planetStart, U1_Research::INDEX, $this->startPoint)->getLevelSumGroup(17)
				)) * 400 / ($count + $detect)
			);

			$planetElementStart = $planetStart->get($this->startPoint);
			$planetElementEnd = $planetEnd->get($this->endPoint);

			if ($spy > 0)
			{
				$strucSpy = array(
					U1_Resource::INDEX =>
						$planetEnd->getInstance(U1_Resource::INDEX, $this->endPoint)
							->getQuantities($this->time),
					U1_Army::INDEX =>
						$this->getStructureAndFinishCompletLists($planetEnd, U1_Army::INDEX, $this->endPoint)
							->getLevelSumGroups(),
					U1_Building::INDEX => $buildingEnd->getLevelSumGroups(),
					U1_Research::INDEX => $researchEnd->getLevelSumGroups()
				);
				//supprime les valeurs vide (=0) et compte le nombre d'élements
				$countStruct = 0;
				foreach ($strucSpy as &$struc)
				{
					SF_Process_Array::removeEmptyValue($struc);
					$countStruct += count($struc);
				}

				$dead = 0;
				//tout n'est pas espionnable
				if ($spy < $countStruct)
				{
					//sonde détruite
					$dead = floor($count * (($countStruct - $spy) / $countStruct));

					$keys = array();
					//recupère chaque clée
					SF_Process_Array::addKeys($keys, $strucSpy, 2);
					$strucSpy = SF_Process_Array::getRecursiveValues(
						$strucSpy,
						//recupère les valeurs des clés précèdement enregistrée
						SF_Process_Array::getValues($keys, array_rand($keys, $spy))
					);
				}

				$this->sendMessage(U1_Display_Move::getReportSpy($planetElementStart, $planetElementEnd, intval($spy/$countStruct*100), $strucSpy, $dead), $dead > 0);

				if ($count <= $dead)
					return true;

				$units->subtractUnit(4, $dead);
			}
			else
			{
				$this->sendMessage(U1_Display_Move::getReportSpy($planetElementStart, $planetElementEnd, 0, array(), $count));
				return true;
			}
		}
		return false;
	}
}